﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace SGUI
{
    public class ASTNode
    {
        public enum ASTNodeType 
        {
          BoolNode,      //bool
          NumberNode,    //数字
          CommentNode,   //注释
          SymbolNode,    //符号 
          StringNode,    //String
          ElementNode,   //元素Node
          ComponentNode, //组件Node
          AttributeNode,  //属性Node
         DefinePropertyNode //定义属性Node
          
         }
        public ASTNodeType NodeType;
        public ASTPos Position;

        public virtual List<ASTNode> Children() { return null; }
        public virtual string String() { return ""; }

        public virtual object GetValue() { return null; }

        public static bool isSemantic(ASTNode n)
        {
            if (n == null)
            {
                return false;
            }
            if (n.GetType() == typeof(CommentNode) )
            {
                return false;
            }
            return true;
        }
    }
    
    public class ElementNode : ASTNode
    {
        public string ElementName;

        public Dictionary<StringNode, ASTNode> Attrs;
    }

    /// <summary>
    /// 注释
    /// </summary>
    public class CommentNode :ASTNode
    {
        public string Val;
        public CommentNode() { this.NodeType = ASTNodeType.CommentNode; }
        public override string String() { return this.Val; }
    }
    /// <summary>
    /// 布尔值
    /// </summary>
    public class BoolNode : ASTNode
    {
        public bool Val;
        public BoolNode() { this.NodeType = ASTNodeType.BoolNode; }

        public override string String()
        {
            return this.Val ? "tue" : "false";
        }
        public override object GetValue()
        {
            return this.Val;
        }
    }
    /// <summary>
    /// 字符串
    /// </summary>
    public class StringNode :ASTNode
    {
        public string Val;
        public StringNode() { this.NodeType = ASTNodeType.StringNode; }
        public override string String() { return this.Val; }
        public override object GetValue()
        {
            return this.Val;
        }
    }
    /// <summary>
    /// 符号
    /// </summary>
    public class SymbolNode :ASTNode
    {
        public string Val;
        public SymbolNode() { this.NodeType = ASTNodeType.SymbolNode; }
        public override string String(){return Val;}

        public override object GetValue()
        {
            return this.Val;
        }
    }

    public class ComponentNode : ASTNode 
    {
        public string ComponentName;
        public List<ASTNode> nodes;
        public ComponentNode() { this.NodeType = ASTNodeType.ComponentNode; }
        public override string String()
        {
            return this.ComponentName;
        }
    }

    public class AttributeNode : ASTNode 
    {
        public string AttrName;
        public ASTNode ValueNode; 

        public AttributeNode() { this.NodeType = ASTNodeType.AttributeNode; }

        public override string String()
        {
            return this.AttrName + ":" + this.ValueNode.ToString();
        }
    }

    public class DefinePropertyNode :ASTNode
    {
        public enum PropertyType 
        {
           String,
           Int,
           Float
        }
        public DefinePropertyNode() { this.NodeType = ASTNodeType.DefinePropertyNode; }
        public override string String()
        {
            return this.propertyType + " " + this.PropertyName + " = " + this.DefaultValue;
        }
        public PropertyType propertyType; 
        public string PropertyName;
        public object DefaultValue;
    }

    public class NumberNode : ASTNode
    {
        public object NumberVal;
        public enum NumberType
        {
            INT,
            DOUBLE, 
        }
        public NumberType Type;
        public NumberNode() { this.NodeType = ASTNodeType.NumberNode; }
        public override string String()
        {
            return "num(" + this.NumberVal.ToString() + ")";
        }

        public override object GetValue()
        {
            return this.NumberVal;
        }
    }


}
